package com.zyfdroid.myessentialx;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mojang.brigadier.CommandDispatcher;

import static net.minecraft.server.command.CommandManager.literal;

import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.*;
import net.minecraft.network.MessageType;
import net.minecraft.recipe.BookCloningRecipe;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.*;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.level.ServerWorldProperties;

import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Predicate;

public class MyMod implements ModInitializer {
	private MinecraftServer server = null;

	HashMap<String,PlayerPosition> backLocations = new HashMap<>();
	public static class PlayerPosition{
		public double posX,posY,posZ;
		public ServerWorld world;

		public PlayerPosition(double posX, double posY, double posZ, ServerWorld world) {
			this.posX = posX;
			this.posY = posY;
			this.posZ = posZ;
			this.world = world;
		}
	}

	HashMap<String,PlayerHome> homes = new HashMap<>();
	HashMap<String,PlayerHome> homesB = new HashMap<>();
	public static class PlayerHome{
	 	public double x,y,z;float yaw,pitch;
		public String levelname="";
		public PlayerHome(double x, double y, double z,float yaw, float pitch) {
			this.x = x;
			this.y = y;
			this.z = z;
			this.yaw = yaw;
			this.pitch = pitch;
		}
	}

	public static void printLogo(){
		System.out.println(
				"MyEssentialX mod Made by\n" +
				".------..------..------..------..------..------..------..------.\n" +
				"|Z.--. ||Y.--. ||F.--. ||D.--. ||R.--. ||O.--. ||I.--. ||D.--. |\n" +
				"| :(): || (\\/) || :(): || :/\\: || :(): || :/\\: || (\\/) || :/\\: |\n" +
				"| ()() || :\\/: || ()() || (__) || ()() || :\\/: || :\\/: || (__) |\n" +
				"| '--'Z|| '--'Y|| '--'F|| '--'D|| '--'R|| '--'O|| '--'I|| '--'D|\n" +
				"`------'`------'`------'`------'`------'`------'`------'`------'");
	}

	@Override
	public void onInitialize() {
		PlayerDeathEvent.EVENT.register(player -> {
			recordLocation(player);
			sendMessage(player,"建议使用 /back 回到死亡地点");
			return ActionResult.PASS;
		});

		ServerLifecycleEvents.SERVER_STARTED.register(minecraftServer -> {
			server = minecraftServer;
			loadHomes();
			loadPois();
			printLogo();
		});

		CommandRegistrationCallback.EVENT.register((commandDispatcher, b) -> {
			commandDispatcher.register(literal("spawn").executes(MyMod.this::execCommandSpawn));
			//commandDispatcher.register(literal("fly").executes(MyMod.this::execCommandFly));
			//commandDispatcher.register(literal("test").executes(MyMod.this::execCommandTest));
			//commandDispatcher.register(literal("sendtrick").then(CommandManager.argument("msg",StringArgumentType.greedyString()).executes(MyMod.this::execCommandSendTrick)));
			commandDispatcher.register(literal("back").executes(MyMod.this::execCommandBack));
			commandDispatcher.register(literal("home").executes(MyMod.this::execCommandHome));
			commandDispatcher.register(literal("sethome").executes(MyMod.this::execCommandSetHome));
			commandDispatcher.register(literal("home2").executes(MyMod.this::execCommandHomeB));
			commandDispatcher.register(literal("sethome2").executes(MyMod.this::execCommandSetHomeB));
			commandDispatcher.register(literal("tpaccept").executes(MyMod.this::execCommandTpAccpet));
			commandDispatcher.register(literal("tpdeny").executes(MyMod.this::execCommandTpDeny));
			commandDispatcher.register(literal("tpask").then(CommandManager.argument("playername",EntityArgumentType.player()).executes(MyMod.this::execCommandTpAsk)));
			commandDispatcher.register(literal("tpinvite").then(CommandManager.argument("playername",EntityArgumentType.player()).executes(MyMod.this::execCommandTpInvite)));
			commandDispatcher.register(literal("warpset").requires(c->c.hasPermissionLevel(3)).then(CommandManager.argument("name", StringArgumentType.word()).executes(MyMod.this::execCommandWarpSet)));
			commandDispatcher.register(literal("warp").then(CommandManager.argument("name", StringArgumentType.word()).executes(MyMod.this::execCommandWarp)));
			commandDispatcher.register(literal("warplist").executes(MyMod.this::execCommandWarpList));
			commandDispatcher.register(literal("suicide").executes(MyMod.this::execCommandSuicide));
		});

//		ServerTickEvents.START_SERVER_TICK.register(new ServerTickEvents.StartTick() {
//			@Override
//			public void onStartTick(MinecraftServer minecraftServer) {
//
//			}
//		});
	}



	final String homeFilePathA="myessentialx_homeA_v2.json";
	final String homeFilePathB="myessentialx_homeB_v2.json";
	Gson JsonConvert = new Gson();

	private static class HomeEntry{public String playerName;public PlayerHome home;

		public HomeEntry(String playerName, PlayerHome home) {
			this.playerName = playerName;
			this.home = home;
		}
	}

	public List<HomeEntry> toHomeEntry(HashMap<String,PlayerHome> target){
		ArrayList<HomeEntry> list = new ArrayList<>();
		for (Map.Entry<String,PlayerHome> ent:target.entrySet()) {
			list.add(new HomeEntry(ent.getKey(),ent.getValue()));
		}
		return list;
	}
	public void loadHomeEntry(List<HomeEntry> entries,HashMap<String,PlayerHome> target){
		target.clear();
		for (HomeEntry ent : entries) {
			target.putIfAbsent(ent.playerName,ent.home);
		}
	}

	private void saveHomes(){
		try {
			String jsonA = JsonConvert.toJson(toHomeEntry(homes));
			saveToStringFile(homeFilePathA,jsonA);
		}catch (Exception ex){
			ex.printStackTrace(System.out);
			System.out.print("严重错误，无法保存玩家的home数据");
		}
		try {
			String jsonB = JsonConvert.toJson(toHomeEntry(homesB));
			saveToStringFile(homeFilePathB,jsonB);
		}catch (Exception ex){
			ex.printStackTrace(System.out);
			System.out.print("严重错误，无法保存玩家的home数据");
		}
	}

	private void saveToStringFile(String path,String content) throws IOException {
		File outFile = new File(path);
		if(outFile.exists()){outFile.delete();}
		outFile.createNewFile();
		FileOutputStream fos = new FileOutputStream(path);
		PrintStream ps = new PrintStream(fos);
		ps.print(content);
		ps.close();
	}

	private String loadFromStringFile(String path) throws IOException {
		FileInputStream fis = new FileInputStream(path);
		BufferedReader br = new BufferedReader(new InputStreamReader(fis));
		String temp;
		StringBuilder result = new StringBuilder();
		while ((temp = br.readLine())!=null){result.append(temp).append("\r\n");}
		br.close();
		return result.toString();
	}

	private void loadHomes(){
		try {
			String jsonA = loadFromStringFile(homeFilePathA);
			List<HomeEntry> homes = JsonConvert.fromJson(jsonA,new TypeToken<List<HomeEntry>>() {}.getType());
			loadHomeEntry(homes,this.homes);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.print("No player homeA is set.");
		}
		try {
			String jsonB = loadFromStringFile(homeFilePathB);
			List<HomeEntry> homes = JsonConvert.fromJson(jsonB,new TypeToken<List<HomeEntry>>() {}.getType());
			loadHomeEntry(homes,this.homesB);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.print("No player homeB is set.");
		}
	}

	private int execCommandBack(CommandContext<ServerCommandSource> serverCommandSourceCommandContext) {
		try{
			ServerPlayerEntity player = serverCommandSourceCommandContext.getSource().getPlayer();
			String name = player.getName().asString();
			if(backLocations.containsKey(name)){
				PlayerPosition pos = backLocations.get(name);
				recordLocation(player);
				player.teleport(pos.world,pos.posX,pos.posY,pos.posZ,0,0);
				sendMessage(player,"正在回到上一个地点");
			}
			else{
				sendMessage(player,"没有上一个地点");
			}

		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private int execCommandSpawn(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			recordLocation(player);
			ServerWorld overworld = server.getOverworld();
			BlockPos spawnpoint = overworld.getSpawnPos();
			player.teleport(overworld,spawnpoint.getX(),spawnpoint.getY(),spawnpoint.getZ(),0,overworld.getSpawnAngle());
			sendMessage(player,"传送到出生点");
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private void recordLocation(ServerPlayerEntity player){
		String name = player.getName().asString();
		backLocations.remove(name);
		backLocations.put(name,new PlayerPosition(player.getX(), player.getY(), player.getZ(),player.getServerWorld()));

		/*
		【管理员】皮卡九<cvraindays@qq.com>  22:59:47
		不，我gty打死都不sethome

		【管理员】皮卡九<cvraindays@qq.com> 2020/10/5 23:26:28
		不如加上
		*/
		if(name.equals("CvRaindays")){
			server.getPlayerManager().broadcastChatMessage(
					new LiteralText("CvRaindays: 真   香")
							.setStyle(Style.EMPTY.withFormatting(Formatting.GREEN)),
					MessageType.SYSTEM,
					player.getUuid());
		}

	}

	private void sendMessage(ServerPlayerEntity player,String text){
		player.sendSystemMessage(new LiteralText("[系统] "+text),player.getUuid());
	}



	private int execCommandFly(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			player.teleport(player.getX(),259,player.getZ());
			objectCommandContext.getSource().sendFeedback(new LiteralText("这是飞一样的感觉~~~~~~~~~~"),false);
//			player.abilities.allowFlying=!player.abilities.allowFlying;
//			player.setSwimming(player.abilities.allowFlying);
//			player.abilities.flying=true;
//			player.updateNeeded=true;
//			objectCommandContext.getSource().sendFeedback(new LiteralText("you are now "+(player.abilities.allowFlying ? "allowed" : "disallowed") +" flying"),false);
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private int execCommandSetHome(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String playername = player.getName().asString();
			PlayerHome home = new PlayerHome(player.getX(),player.getY(),player.getZ(), player.getYaw(), player.getPitch());
			home.levelname=getServerWorldName(player.getServerWorld());
			homes.remove(playername);
			homes.put(playername,home);
			sendMessage(player,"已设置家.");
			if (!homesB.containsKey(playername)) {
				sendMessage(player,"提示：你可以用 /sethome2 设置另一个家");
			}
			saveHomes();
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private int execCommandHome(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String playername = player.getName().asString();
			if(homes.containsKey(playername)){
				recordLocation(player);
				PlayerHome home = homes.get(playername);
				player.teleport(getServerWorldByName(home.levelname),home.x,home.y,home.z,home.yaw,home.pitch);
				sendMessage(player,"已传送到家");
			}
			else{
				sendMessage(player,"你没有设置家。使用/sethome设置");
			}
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private int execCommandSetHomeB(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String playername = player.getName().asString();
			PlayerHome home = new PlayerHome(player.getX(),player.getY(),player.getZ(), player.getYaw(), player.getPitch());
			home.levelname=getServerWorldName(player.getServerWorld());
			homesB.remove(playername);
			homesB.put(playername,home);
			sendMessage(player,"已设置另一个家.");
			saveHomes();
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	private int execCommandHomeB(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String playername = player.getName().asString();
			if(homesB.containsKey(playername)){
				recordLocation(player);
				PlayerHome home = homesB.get(playername);
				player.teleport(getServerWorldByName(home.levelname),home.x,home.y,home.z,home.yaw,home.pitch);
				sendMessage(player,"已传送到另一个家");
			}
			else{
				sendMessage(player,"你没有设置另一个家。使用/sethome2设置");
			}
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	public HashMap<String, PlayerTeleportActivity> teleportRequestments = new HashMap<>();
	public HashMap<String, PlayerTeleportActivity> teleportInvites = new HashMap<>();

	public static class PlayerTeleportActivity {
		public ServerPlayerEntity from;
		public ServerPlayerEntity to;
		public long expires;

		public PlayerTeleportActivity(ServerPlayerEntity from, ServerPlayerEntity to, long expires) {
			this.from = from;
			this.to = to;
			this.expires = expires;
		}
	}

	final long tpaInvalidDuration=120000;

	private void checkTpExpires(HashMap<String,PlayerTeleportActivity> list){
		List<String> invalids=new ArrayList<>();
		for (String key :list.keySet()) {
			if(list.get(key).expires < System.currentTimeMillis()){
				invalids.add(key);
			}
		}
		for (String key:invalids){
			list.remove(key);
		}
	}

	private int execCommandTpAsk(CommandContext<ServerCommandSource> objectCommandContext){
		try {
			ServerPlayerEntity target = (EntityArgumentType.getPlayer(objectCommandContext,"playername"));
			ServerPlayerEntity sender = objectCommandContext.getSource().getPlayer();
			sendMessage(target,sender.getName().asString()+" 请求传送到你的位置");
			sendMessage(target,"输入 /tpaccept 允许，输入 /tpdeny 拒绝。有效期120秒");
			target.sendSystemMessage(new LiteralText("点击同意").setStyle(Style.EMPTY.withFormatting(Formatting.AQUA,Formatting.BOLD,Formatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/tpaccept"))),sender.getUuid());
			target.sendSystemMessage(new LiteralText("点击拒绝").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED,Formatting.BOLD,Formatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/tpdeny"))),sender.getUuid());
			sendMessage(sender,"请求已经发送给 "+target.getName().asString());
			checkTpExpires(teleportRequestments);
			String key = target.getName().asString();
			teleportRequestments.remove(key);
			teleportRequestments.put(key,new PlayerTeleportActivity(sender,target,System.currentTimeMillis()+tpaInvalidDuration));
		}catch (Exception ex){
			ex.printStackTrace(System.out);
			objectCommandContext.getSource().sendFeedback( new LiteralText("错误的玩家名称"),false);
		}
		return 1;
	}

	private int execCommandTpInvite(CommandContext<ServerCommandSource> objectCommandContext){
		try {
			ServerPlayerEntity target = (EntityArgumentType.getPlayer(objectCommandContext,"playername"));
			ServerPlayerEntity sender = objectCommandContext.getSource().getPlayer();
			sendMessage(target,sender.getName().asString()+" 邀请你去对方的位置");
			sendMessage(target,"输入 /tpaccept 允许，输入 /tpdeny 拒绝。有效期120秒");
			target.sendSystemMessage(new LiteralText("点击同意").setStyle(Style.EMPTY.withFormatting(Formatting.AQUA,Formatting.BOLD,Formatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/tpaccept"))),sender.getUuid());
			target.sendSystemMessage(new LiteralText("点击拒绝").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED,Formatting.BOLD,Formatting.UNDERLINE).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/tpdeny"))),sender.getUuid());
			sendMessage(sender,"请求已经发送给 "+target.getName().asString());
			checkTpExpires(teleportInvites);
			String key = target.getName().asString();
			teleportInvites.remove(key);
			teleportInvites.put(key,new PlayerTeleportActivity(target,sender,System.currentTimeMillis()+tpaInvalidDuration));
		}catch (Exception ex){
			ex.printStackTrace(System.out);
			objectCommandContext.getSource().sendFeedback( new LiteralText("错误的玩家名称"),false);
		}
		return 1;
	}

	private int execCommandTpAccpet(CommandContext<ServerCommandSource> objectCommandContext){
		try {
			ServerPlayerEntity sender = objectCommandContext.getSource().getPlayer();
			String key = sender.getName().asString();
			checkTpExpires(teleportInvites);
			checkTpExpires(teleportRequestments);
			if(teleportRequestments.containsKey(key)){
				PlayerTeleportActivity activity = teleportRequestments.get(key);
				ServerPlayerEntity from = activity.from;
				recordLocation(from);
				ServerPlayerEntity to = activity.to;
				from.teleport(to.getServerWorld(),to.getX(),to.getY(),to.getZ(),to.getYaw(),to.getPitch());
				sendMessage(from,"对方已接受邀请，传送到"+to.getName().asString());
				teleportRequestments.remove(key);
			}
			else if(teleportInvites.containsKey(key)){
				PlayerTeleportActivity activity = teleportInvites.get(key);
				ServerPlayerEntity from = activity.from;
				recordLocation(from);
				ServerPlayerEntity to = activity.to;
				from.teleport(to.getServerWorld(),to.getX(),to.getY(),to.getZ(),to.getYaw(),to.getPitch());
				sendMessage(to,from.getName().asString()+"已接受邀请并传送了过来");
				teleportInvites.remove(key);
			}
			else{
				sendMessage(sender,"没有最近的传送请求");
			}

		}catch (Exception ex){
			ex.printStackTrace(System.out);
			objectCommandContext.getSource().sendFeedback( new LiteralText("错误的玩家名称"),false);
		}
		return 1;
	}
	private int execCommandTpDeny(CommandContext<ServerCommandSource> objectCommandContext){
		try {
			ServerPlayerEntity sender = objectCommandContext.getSource().getPlayer();
			String key = sender.getName().asString();
			checkTpExpires(teleportInvites);
			checkTpExpires(teleportRequestments);
			if(teleportRequestments.containsKey(key)){
				PlayerTeleportActivity activity = teleportRequestments.get(key);
				ServerPlayerEntity from = activity.from;
				ServerPlayerEntity to = activity.to;
				sendMessage(from,"对方拒绝传送到"+to.getName().asString());
				teleportRequestments.remove(key);
			}
			else if(teleportInvites.containsKey(key)){
				PlayerTeleportActivity activity = teleportInvites.get(key);
				ServerPlayerEntity from = activity.from;
				ServerPlayerEntity to = activity.to;
				sendMessage(to,from.getName().asString()+"拒绝了传送邀请");
				teleportInvites.remove(key);
			}
			else{
				sendMessage(sender,"没有最近的传送请求");
			}

		}catch (Exception ex){
			ex.printStackTrace(System.out);
			objectCommandContext.getSource().sendFeedback( new LiteralText("错误的玩家名称"),false);
		}
		return 1;
	}

	private String[] suicideMessages = new String[]{
			"宁死不屈",
			"A W S L"
	};
	Random rnd = new Random();
	private int execCommandSuicide(CommandContext<ServerCommandSource> objectCommandContext){
		try {
			ServerPlayerEntity sender = objectCommandContext.getSource().getPlayer();
			sender.kill();
			server.getPlayerManager().broadcastChatMessage(
					new LiteralText("["+sender.getName().asString()+" 的遗言] "+suicideMessages[rnd.nextInt(suicideMessages.length)])
							.setStyle(Style.EMPTY.withFormatting(Formatting.GOLD)), MessageType.SYSTEM,sender.getUuid());
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}

	final String warpFilePath="myessentialx_pois.json";
	HashMap<String,PlayerHome> pointOfInterests = new HashMap<>();

	private void loadPois(){
		try {
			String json = loadFromStringFile(warpFilePath);
			List<HomeEntry> pois = JsonConvert.fromJson(json,new TypeToken<List<HomeEntry>>() {}.getType());
			loadHomeEntry(pois,pointOfInterests);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.print("No POI is set.");
		}
	}

	private void savePois(){
		try {
			String json = JsonConvert.toJson(toHomeEntry(pointOfInterests));
			saveToStringFile(warpFilePath,json);
		}catch (Exception ex){
			ex.printStackTrace(System.out);
			System.out.print("严重错误，无法保存poi数据");
		}
	}

	public String getServerWorldName(ServerWorld world){
		try {
			return world.getRegistryKey().getValue().toString();
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Error when get server world name");
		}
		return "";
	}

	public ServerWorld getServerWorldByName(String name){
		for (ServerWorld wld :
				server.getWorlds()) {
			if(getServerWorldName(wld).equals(name)){return wld;}
		}
		System.out.println("Cannot find world with name "+name);
		return null;
	}

	private int execCommandWarpSet(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String poiname = StringArgumentType.getString(objectCommandContext,"name");
			player.getServerWorld();

			PlayerHome home = new PlayerHome(player.getX(),player.getY(),player.getZ(), player.getYaw(), player.getPitch());
			home.levelname=getServerWorldName(player.getServerWorld());
			pointOfInterests.remove(poiname);
			pointOfInterests.put(poiname,home);
			sendMessage(player,"已设置传送点.");
			savePois();
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}
	private int execCommandWarp(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			String poiname = StringArgumentType.getString(objectCommandContext,"name");
			if(pointOfInterests.containsKey(poiname)){
				recordLocation(player);
				PlayerHome home = pointOfInterests.get(poiname);
				player.teleport(getServerWorldByName(home.levelname),home.x,home.y,home.z,home.yaw,home.pitch);
				sendMessage(player,"已传送到"+poiname);
			}
			else{
				sendMessage(player,"没有这个传送点");
			}
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}
	private int execCommandWarpList(CommandContext<ServerCommandSource> objectCommandContext){
		try{
			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
			sendMessage(player,"可用的传送点有：");
			for (String key:
				 pointOfInterests.keySet()) {
				objectCommandContext.getSource().sendFeedback(new LiteralText("     "+key).setStyle(Style.EMPTY.withFormatting(Formatting.AQUA).withFormatting(Formatting.UNDERLINE).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,new LiteralText("点击传送"))).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,"/warp "+key))),false);
			}
		}catch (Exception ex){
			ex.printStackTrace(System.out);
		}
		return 1;
	}
//
//	private int execCommandTest(CommandContext<ServerCommandSource> objectCommandContext){
//		try{
//			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
//
//			MutableText text = new LiteralText("abc");
//			text = text.append("nbb");
//
//			ItemStack bookItem = new ItemStack(Items.WRITTEN_BOOK);
//			CompoundTag tag = new CompoundTag();
//			tag.putString("title","命令使用指南");
//			tag.putString("author","ZYFDroid");
//			tag.putBoolean("resolved",false);
//			tag.putInt("generation",0);
//			ListTag pages = new ListTag();
//			pages.add(StringTag.of("{\"text\":\"shioshiog\"}"));
//			pages.add(StringTag.of("{\"text\":\"shioshiog\"}"));
//			pages.add(StringTag.of("{\"text\":\"shioshiog\"}"));
//			tag.put("pages",pages);
//			bookItem.setTag(tag);
//
//			ItemEntity entity = new ItemEntity(player.getServerWorld(),player.getX(),player.getY(),player.getZ(),bookItem);
//			player.getServerWorld().spawnEntity(entity);
//
//		}catch (Exception ex){
//			ex.printStackTrace(System.out);
//		}
//		return 1;
//	}
//
//
//	private int execCommandSendTrick(CommandContext<ServerCommandSource> objectCommandContext){
//		try{
//			ServerPlayerEntity player = objectCommandContext.getSource().getPlayer();
//			MutableText text = new LiteralText("<"+player.getName().asString()+"> 点击右边蓝色字体有惊喜 ");
//			MutableText action = new LiteralText("点我").setStyle(Style.EMPTY.withFormatting(Formatting.BLUE).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,StringArgumentType.getString(objectCommandContext,"msg"))));
//
//			server.getPlayerManager().broadcastChatMessage(text.append(action),MessageType.SYSTEM,player.getUuid());
//
//		}catch (Exception ex){
//			ex.printStackTrace(System.out);
//		}
//		return 1;
//	}


}
